"""MainServer Class for Pluster"""
from service.XMLRPC import *
from service.PlusterLog import *
from MVC.plstdocument import IDocument
from service.XMLRPC import *
from service.rrd import Rrd
from service.pconfig import PConfig
from service.exception import *
import os.path
import glob
import time
import traceback
import socket
class NodeDocument(PlusterLog):
    """Contain All info of a node in server side"""
    def __init__(self,obj):
        PlusterLog.__init__(self)
        try:
            self.ip=obj.get_ip()
            self.port=obj.get_port()
            self.name=obj.get_name()
            self.mac=obj.get_mac()
            self.rpc_object=obj
            self.time=time.ctime()
            self.cpu_num,self.hz,self.cpu_type=obj.get_cpu_info()
            self.total_mem=obj.get_mem_info()[0]
        except socket.error:
            self.log.debug("Get node attribute error")
            raise


    def is_alive(self):
        try:
            stat=self.rpc_object.is_alive()
        except:
            return False
        else:
            return True

    def kill(self):
        """Close remote node"""
        self.rpc_object.stop()

    def keep_alive (self):
        """ Set flag in remote side to keep remote node alive"""
        self.rpc_object.keep_alive()


    def load_remote_task(self,task_name,node_ip,port,*arg):
        return self.rpc_object.load_remote_task(task_name,\
                                                    node_ip,port,\
                                                    arg)
    def update_ps(self):
        self.rpc_object.update_ps()

    def update_node(self):
        #TODO fix it, Update all
        return self.rpc_object.get_usage()


    def get_host_name(self):
        return self.name

    def get_ip(self):
        return self.ip

    def get_port(self):
        return self.port

    def get_mac(self):
        return self.mac

    def is_running_user(self,name):
        return self.rpc_object.is_running_user(name)

    def get_user_usage(self,user):
        return self.rpc_object.get_user_usage(user)
__doc__="""
Usage:
     xmlrpcDaemon=XMLRPC()

     mainServer=MainServer()

     p=xmlrpcDaemon.RequestPort(mainServer)#Now remote node could
     invoke RegisterNode()

     xmlrpcDaemon.ReleasePort(p)
"""
#global xmlrpcDeamon. Other modulas must import MainServer and use
#MainServer to see it

class MainServer(PlusterLog,IDocument):

    '''MainServer is a base class .it provides method to manage tasks
    and nodes also control ports allocation.'''

    def RegisterNode(self,addr):
        """addr=string of remote node IP address
        Remote node call this method to register itself to Server
        This method do the following things
        1.add remote node object to node_list
        2.create new icon for that node
        3.notify UI to update"""
        self.log.info("Node Registed from  "+addr)
        try:
            node=xmlrpclib.Server(addr)
            node.keep_alive()
            node_doc=NodeDocument(node)
            self.node_list[node_doc.ip+str(node_doc.port)]=node_doc
        except socket.error:
            self.log.error("RegisterNoder error. Can not register node "+addr)
            raise
        else:
            self.log.info("New Node %s registed ok"%addr)
            rrd=PConfig.attribute.rrd_path+node_doc.name+".rrd"
            icon=PConfig.attribute.rrd_path+"png/"\
                  +node_doc.name+"_ico.png"
            if not os.path.exists(rrd):
                Rrd.tool.create_node(node_doc.name)
                PConfig.attribute.add_node()
                self.log.info("Create rrd file %s"%rrd)
            Rrd.tool.draw_node(node_doc.name,"-2h","now","icon")
            self.Flush()
        return 0

    def KillNode(self,ip,port):
        """addr = string of remote node
        Remove node from server."""
        try:
            del self.node_list[ip+str(port)]
        except KeyError:
            self.log.error("kill Node %s err. Can not find key"%ip)
            raise
        except:
            self.log.error("KillNode() unknown error")
            raise
        else:
            self.log.info("Node: %s %d disconnect"%(ip,port))
            self.Flush()
        return 0

    def get_node_list(self):
        """Return a list of all the key in self.list_dict """
        return self.node_list.values()

    def get_node(self,host_name):
        for node in self.node_list.values():
            if node.name==host_name:
                return node
            continue
        self.log.debug("Could not find node %s"%host_name)
        raise MainServerNoNodeError

    obj=None

    def __init__(self,address):
        PlusterLog.__init__(self)
        IDocument.__init__(self)
        self.node_list={}
        self.port=XMLRPC.rpcDaemon.RequestPort(self)
        self.address=address
        self.log.info("Main Server Start")
        MainServer.obj=self

    def __del__(self):
        XMLRPC.rpcDaemon.ReleasePort(self.port)

